#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
多模态分析器主模块
用于视频分析和异常检测
"""

import base64
import cv2
import time
import numpy as np
import json
import httpx
import os
import datetime
import asyncio
import requests

from utility import video_chat_async, chat_request, insert_txt
from config import RAGConfig
from prompt import prompt_detect, prompt_summary, prompt_video


class MultiModalAnalyzer:
    def __init__(self):
        self.message_queue = []
        self.time_step_story = []

    def trans_date(self,date_str):
        try:
            # 尝试分割时间戳
            parts = date_str.split('-')
            
            # 根据分割后的部分数量确定格式
            if len(parts) == 6:  # 完整格式: 年-月-日-时-分-秒
                year, month, day, hour, minute, second = parts
                
                # 确定上午/下午
                am_pm = "上午" if int(hour) < 12 else "下午"
                
                # 转换为12小时制
                hour_12 = hour if hour == '12' else str(int(hour) % 12)
                
                # 返回格式化的日期和时间字符串
                return f"{year}年{int(month)}月{int(day)}日{am_pm}{hour_12}点（{hour}时）{int(minute)}分{int(second)}秒"
                
            elif len(parts) == 3:  # 简化格式: 00-00-秒
                # 使用当前日期
                now = datetime.datetime.now()
                year = str(now.year)
                month = str(now.month)
                day = str(now.day)
                hour = parts[0] if parts[0] != '00' else '00'
                minute = parts[1] if parts[1] != '00' else '00'
                second = parts[2]
                
                # 简化的时间字符串
                if hour == '00' and minute == '00':
                    return f"视频第{int(second)}秒"
                else:
                    return f"{hour}时{minute}分{second}秒"
            
            else:  # 其他格式
                # 简单返回原始时间戳
                return f"时间点: {date_str}"
                
        except Exception as e:
            print(f"时间戳转换错误: {e}, 时间戳: {date_str}")
            # 出错时返回原始时间戳
            return f"时间点: {date_str}"
    
    async def analyze(self, frames, fps=20, timestamps=None):
        try:
            start_time = time.time()
            
            # 检查输入参数
            if not frames or len(frames) == 0:
                print("错误: 没有帧可以分析")
                return {"alert": "分析错误: 没有视频帧可以处理", "error": True}
                
            # 确保video_warning目录存在
            os.makedirs('./video_warning', exist_ok=True)
            
            # 准备历史记录
            histroy = "录像视频刚刚开始。"
            Recursive_summary = ""
            if self.message_queue:
                for i in self.message_queue:
                    histroy = "历史视频内容总结:"+Recursive_summary+"\n\n当前时间段：" + i['start_time']+"  - " + i['end_time'] + "\n该时间段视频描述如下：" +i['description'] + "\n\n该时间段异常提醒:"+i['is_alert']
            
            # 并行处理视频描述和历史总结
            print("开始分析视频内容...")
            time_temp = time.time()
            tasks = [chat_request(prompt_summary.format(histroy=histroy)), video_chat_async(prompt_video, frames, timestamps, fps=fps)]
            results = await asyncio.gather(*tasks)
           
            Recursive_summary = results[0]
            description = results[1]
            description_time = time.time()-time_temp
            print(f"视频分析完成，耗时: {description_time:.2f}秒")
            
            # 检查视频描述是否包含错误信息
            if description.startswith("视频处理过程中出错") or description.startswith("API请求失败") or description.startswith("处理API响应时出错"):
                print(f"视频分析过程中出错: {description}")
                return {"alert": f"分析错误: {description}", "error": True}
    
            # 如果没有时间戳，直接返回描述
            if timestamps is None:
                return {"description": description}
            
            # 格式化日期并保存历史记录
            date_flag = self.trans_date(timestamps[0])+"："
            
            # 保存监控视频描述
            if RAGConfig.ENABLE_RAG:
                print("RAG已启用，保存到向量数据库")
                insert_txt([date_flag+description], 'table_test_table')
            else:
                print("RAG未开启，保存到本地文件")
                # 本地文件保存
                try:
                    with open(RAGConfig.HISTORY_FILE, 'a', encoding='utf-8') as file:
                        file.write(date_flag+description + '\n')
                    print("历史消息保存成功")
                except Exception as e:
                    print(f"保存历史消息失败: {e}")
            
            # 异常检测
            print("开始进行异常检测...")
            text = prompt_detect.format(Recursive_summary=Recursive_summary, 
                                       current_time=timestamps[0]+"  - "+timestamps[-1], 
                                       latest_description=description)
            
            time_temp = time.time()
            alert = await chat_request(text)
            alert_time = time.time() - time_temp
            
            print("警告内容：", alert)    
            print("\n下面是视频描述原文：")
            print(description)
            
            print(f"视频分析总耗时: {time.time() - start_time:.2f}秒")
            print(f"视频描述用时: {description_time:.2f}秒, 警告文本用时: {alert_time:.2f}秒")
            
            # 处理异常情况
            if "无异常" not in alert:
                print("检测到异常情况，保存警告视频和截图")
                try:
                    # 生成文件名
                    current_time = timestamps[0]
                    file_str = f"warning_{current_time}"
                    
                    # 检查输出文件是否存在
                    output_files = ["output.mp4", "output.avi"]
                    output_file = None
                    
                    for f in output_files:
                        if os.path.exists(f"./video_warning/{f}"):
                            output_file = f
                            break
                    
                    if output_file:
                        # 重命名文件
                        new_file_name = f"video_warning/{file_str}.{output_file.split('.')[-1]}"
                        os.rename(f"./video_warning/{output_file}", new_file_name)
                        print(f"警告视频已保存为: {new_file_name}")
                        
                        # 保存第一帧作为截图
                        frame = frames[0]
                        if frame.dtype != np.uint8:
                            frame = frame.astype(np.uint8)
                        if len(frame.shape) == 2:
                            # 如果帧是灰度的，转换为BGR
                            frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR) 
                        cv2.imwrite(f"video_warning/{file_str}.jpg", frame)
                        print(f"警告截图已保存为: video_warning/{file_str}.jpg")
                        
                        # 返回警告信息
                        return {
                            "alert": f"<span style=\"color:red;\">{alert}</span>",
                            "description": f'当前10秒监控消息描述：\n{description}`\n\n历史监控内容:\n{Recursive_summary}`',
                            "video_file_name": f"{file_str}.{output_file.split('.')[-1]}",
                            "picture_file_name": f"{file_str}.jpg"
                        }
                    else:
                        print("警告：未找到输出视频文件")
                        return {
                            "alert": f"<span style=\"color:red;\">{alert}</span>",
                            "description": f'当前10秒监控消息描述：\n{description}`\n\n历史监控内容:\n{Recursive_summary}`',
                            "error": "未找到输出视频文件"
                        }
                except Exception as e:
                    print(f"保存警告视频或截图时出错: {e}")
                    return {
                        "alert": f"<span style=\"color:red;\">{alert}</span>",
                        "description": f'当前10秒监控消息描述：\n{description}`\n\n历史监控内容:\n{Recursive_summary}`',
                        "error": str(e)
                    }
            
            # 更新消息队列
            if timestamps:
                self.message_queue.append({ 
                    'start_time': timestamps[0],
                    'end_time': timestamps[1],
                    'description': description, 
                    'is_alert': alert
                })
    
                # 只保留最近15条消息用作历史信息总结
                self.message_queue = self.message_queue[-15:]
                
            # 返回无异常结果
            return {"alert": "无异常"}
            
        except Exception as e:
            print(f"分析过程中发生错误: {e}")
            import traceback
            traceback.print_exc()
            
            # 生成文件名
            if timestamps and len(timestamps) > 0:
                current_time = timestamps[0]
                file_str = f"warning_{current_time}"
                
                # 保存第一帧作为截图（如果有帧）
                if frames and len(frames) > 0:
                    try:
                        frame = frames[0]
                        if frame.dtype != np.uint8:
                            frame = frame.astype(np.uint8)
                        if len(frame.shape) == 2:
                            # 如果帧是灰度的，转换为BGR
                            frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR) 
                        cv2.imwrite(f"video_warning/{file_str}.jpg", frame)
                        print(f"错误截图已保存为: video_warning/{file_str}.jpg")
                    except Exception as img_error:
                        print(f"保存错误截图时出错: {img_error}")
            
            return {
                "alert": f"分析错误: {str(e)}", 
                "error": True,
                "description": f"视频分析过程中出错: {str(e)}"
            }
